package com.apimarket.advice;

import com.apimarket.entity.Result;
import com.apimarket.enums.InvalidTypeEnum;
import com.apimarket.enums.NetContextEnum;
import com.apimarket.exception.InvalidTypeException;
import com.apimarket.exception.NetContextException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;

import java.net.URISyntaxException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;

/**
 * 全局异常处理器(后期会合并)
 *
 * @author yyc
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger logger = LogManager.getLogger(GlobalExceptionHandler.class);


    /**
     * 处理校验异常
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public Result<String> bindValidErrorHandler(MethodArgumentNotValidException e) {
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        StringBuilder builder = new StringBuilder();
        for (ObjectError error : errors) {
            builder.append(error.getDefaultMessage()).append(";");
        }
        return new Result<>(builder.toString(), 400, "fail");
    }

    /**
     * NetContext异常处理
     */
    @ExceptionHandler(value = {NetContextException.class})
    public Result<String> netContextExceptionHandler(NetContextException e) {
        NetContextEnum netContextEnum = e.getNetContextEum();
        return new Result<>(netContextEnum.getMessage(), netContextEnum.getCode(), netContextEnum.getMessage());
    }

    /**
     * InvalidType异常处理
     */
    @ExceptionHandler(value = {InvalidTypeException.class})
    public Result<String> InvalidTypeExceptionHandler(InvalidTypeException e) {
        InvalidTypeEnum invalidTypeEnum = e.getInvalidTypeEnum();
        return new Result<>(invalidTypeEnum.getMessage(), invalidTypeEnum.getCode(), "fail");
    }

    /**
     * url地址解析异常
     */
    @ExceptionHandler(value = {URISyntaxException.class})
    public Result<String> urlCheckExceptionHandler(URISyntaxException e) {
        return new Result<>(e.getMessage(), 400, "fail");
    }

    @ExceptionHandler(value = {RedisConnectionFailureException.class})
    public Result<String> unConnnectRedis(RedisConnectionFailureException e){
        return new Result<>("没有连接上Redis",400,"fail");
    }
    @ExceptionHandler(value = {SQLIntegrityConstraintViolationException.class})
    public Result<String> pathNameDuplicate(SQLIntegrityConstraintViolationException e){
        logger.error(e.getMessage());
        return new Result<>("route的path重复",400,"route的path重复");
    }
    //或者@NotNull注解的message提示信息
    @ExceptionHandler(value = {BindException.class})
    public Result<String> paramsError(BindException e){

        return new Result<>(e.getBindingResult().getFieldError().getDefaultMessage(),400,"fail");
    }
    /*@ExceptionHandler(value = {MultipartException.class})
    public Result<String> sizeLimitExceededException(MultipartException e){

        return new Result<>(e.getMessage(),400,"fail");
    }*/
    /**
     * 处理未知异常
     */
    /*@ExceptionHandler(value = {Exception.class})
    public Result<String> bindUnknownExceptionHandler(Exception e) {
        logger.error(e.getMessage());
        return new Result<>("系统异常", 500, "fail");
    }*/
}
